package cn.labbook.bluetooth.controller;


import cn.labbook.bluetooth.common.ResultDto;
import cn.labbook.bluetooth.common.TokenManager;
import cn.labbook.bluetooth.constant.AmmeterConstant;
import cn.labbook.bluetooth.entity.*;
import cn.labbook.bluetooth.entity.excel.TenantPayTemplate;
import cn.labbook.bluetooth.entity.wxpay.WXPay;
import cn.labbook.bluetooth.service.*;
import cn.labbook.bluetooth.util.DownloadUtils;
import cn.labbook.bluetooth.util.StringUtils;
import cn.labbook.bluetooth.util.weixin.pay.PayUtil;
import cn.labbook.bluetooth.util.weixin.pay.UUIDHexGenerator;
import cn.labbook.bluetooth.util.weixin.pay.XmlUtil;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.extern.slf4j.Slf4j;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 * 前端控制器
 * </p>
 *
 * @author lonzy
 * @since 2019-03-26
 */
@Slf4j
@Controller
@RequestMapping("/tenantPay")
public class TenantPayController extends AbstractController {

    @Autowired
    ITenantAmmeterPayViewService tenantAmmeterPayViewService;
    @Autowired
    ITenantPayService tenantPayService;
    @Autowired
    IAmmeterService ammeterService;
    @Autowired
    IUserService userService;
    @Autowired
    IAdminService adminService;
    @Autowired
    private ITransferRecordService transferRecordService;
    @Autowired
    private ITransferAmmeterRecordViewService transferAmmeterRecordViewService;


    @RequestMapping({"page"})
    @ResponseBody
    public ResultDto page(Page<TenantAmmeterPayView> page, String ammeterId, String timeBegin, String timeEnd) {
        LambdaQueryWrapper<TenantAmmeterPayView> lambda = (new QueryWrapper()).lambda();
        lambda.eq(TenantAmmeterPayView::getManagerId, TokenManager.getToken().getAdminId());
        lambda.eq(StringUtils.isNotBlank(ammeterId), TenantAmmeterPayView::getAmmeterId, ammeterId);
        lambda.eq(TenantAmmeterPayView::getIsArrive, Integer.valueOf(0));
        lambda.between((StringUtils.isNotBlank(timeBegin) && StringUtils.isNotBlank(timeEnd)), TenantAmmeterPayView::getPayTime, timeBegin, timeEnd);
        IPage<TenantAmmeterPayView> result = this.tenantAmmeterPayViewService.page((IPage) page, (Wrapper) lambda);
        return (result.getTotal() > 0L) ? success(page) : fail("赞无数据");
    }

    @RequestMapping({"pageAdmin"})
    @ResponseBody
    public ResultDto pageAdmin(Page<TenantAmmeterPayView> page, String ammeterId, String timeBegin, String timeEnd, String status) {
        LambdaQueryWrapper<TenantAmmeterPayView> lambda = (new QueryWrapper()).lambda();
        lambda.eq(StringUtils.isNotBlank(ammeterId), TenantAmmeterPayView::getAmmeterId, ammeterId);
        lambda.between((StringUtils.isNotBlank(timeBegin) && StringUtils.isNotBlank(timeEnd)), TenantAmmeterPayView::getPayTime, timeBegin, timeEnd);
        if (StringUtils.isNotBlank(status))
            if (status.equals("1")) {
                lambda.eq(TenantAmmeterPayView::getPayStatus, Integer.valueOf(0));
                lambda.eq(TenantAmmeterPayView::getIsArrive, Integer.valueOf(0));
            } else if (status.equals("2")) {
                lambda.eq(TenantAmmeterPayView::getPayStatus, Integer.valueOf(0));
                lambda.eq(TenantAmmeterPayView::getIsArrive, Integer.valueOf(1));
            } else if (status.equals("0")) {
                lambda.eq(TenantAmmeterPayView::getPayStatus, Integer.valueOf(1));
            }
        lambda.orderByDesc(TenantAmmeterPayView::getPayTime);
        IPage<TenantAmmeterPayView> result = this.tenantAmmeterPayViewService.page(page, lambda);
        return (result.getTotal() > 0L) ? success(page) : fail("暂无数据");
    }

    @RequestMapping({"transferPageAdmin"})
    @ResponseBody
    public ResultDto transferPageAdmin(Page<TransferAmmeterRecordView> page, String ammeterId, String mobile, String timeBegin, String timeEnd, String status) {
        LambdaQueryWrapper<TransferAmmeterRecordView> lambda = (new QueryWrapper().lambda());
        lambda.eq(StringUtils.isNotBlank(ammeterId), TransferAmmeterRecordView::getAmmeterId, ammeterId);
        lambda.eq(StringUtils.isNotBlank(mobile), TransferAmmeterRecordView::getMobile, mobile);
        lambda.between((StringUtils.isNotBlank(timeBegin) && StringUtils.isNotBlank(timeEnd)), TransferAmmeterRecordView::getTransferTime, timeBegin, timeEnd);
        if (StringUtils.isNotBlank(status)) {
            if (status.equals("1")) {
                lambda.eq(TransferAmmeterRecordView::getStatus, Integer.valueOf(1));
            } else if (status.equals("2")) {
                lambda.eq(TransferAmmeterRecordView::getStatus, Integer.valueOf(2));
            }
        }
        lambda.orderByDesc(TransferAmmeterRecordView::getTransferTime);
        IPage<TransferAmmeterRecordView> result = this.transferAmmeterRecordViewService.page(page, lambda);
        return (result.getTotal() > 0L ? success(page) : fail("暂无数据"));
    }

    @RequestMapping({"guestRecharge"})
    public ResponseEntity<byte[]> guestRecharge(String ammeterId, String timeBegin, String timeEnd) throws Exception {
        LambdaQueryWrapper<TenantAmmeterPayView> lambda = (new QueryWrapper()).lambda();
        lambda.eq(TenantAmmeterPayView::getManagerId, TokenManager.getToken().getAdminId());
        lambda.eq(StringUtils.isNotBlank(ammeterId), TenantAmmeterPayView::getAmmeterId, ammeterId);
        lambda.eq(TenantAmmeterPayView::getIsArrive, Integer.valueOf(0));
        lambda.between((StringUtils.isNotBlank(timeBegin) && StringUtils.isNotBlank(timeEnd)), TenantAmmeterPayView::getPayTime, timeBegin, timeEnd);
        lambda.orderByDesc(TenantAmmeterPayView::getPayTime);
        List<TenantAmmeterPayView> list = this.tenantAmmeterPayViewService.list((Wrapper) lambda);
        List<TenantPayTemplate> collect = list.stream().map(l -> TenantPayTemplate.build(l)).collect(Collectors.toList());
        Map<String, String> map = new HashMap<>();
        map.put("ammeterId", "电表号");
        map.put("payTime", "充值时间");
        map.put("payAmouont", "充值金额");
        map.put("managerAmount", "到账金额");
        map.put("payTrueAmouont", "写入电表金额");
        map.put("wxPlatformAmount", "微信平台费");
        map.put("zkisPlatformAmount", "电表运营费");
        return DownloadUtils.downloadExcel(TenantPayTemplate.class, collect, map, "充值流水统计");
    }

    @RequestMapping({"guestRechargeAdmin"})
    public ResponseEntity<byte[]> guestRechargeAdmin(String ammeterId, String timeBegin, String timeEnd) throws Exception {
        LambdaQueryWrapper<TenantAmmeterPayView> lambda = (new QueryWrapper()).lambda();
        lambda.eq(StringUtils.isNotBlank(ammeterId), TenantAmmeterPayView::getAmmeterId, ammeterId);
        lambda.eq(TenantAmmeterPayView::getIsArrive, Integer.valueOf(0));
        lambda.between((StringUtils.isNotBlank(timeBegin) && StringUtils.isNotBlank(timeEnd)), TenantAmmeterPayView::getPayTime, timeBegin, timeEnd);
        List<TenantAmmeterPayView> list = this.tenantAmmeterPayViewService.list((Wrapper) lambda);
        List<TenantPayTemplate> collect = list.stream().map(l -> TenantPayTemplate.build(l)).collect(Collectors.toList());
        Map<String, String> map = new HashMap<>();
        map.put("ammeterId", "电表号");
        map.put("payTime", "充值时间");
        map.put("payAmouont", "充值金额");
        map.put("managerAmount", "到账金额");
        map.put("payTrueAmouont", "写入电表金额");
        map.put("wxPlatformAmount", "微信平台费");
        map.put("zkisPlatformAmount", "电表运营费");
        return DownloadUtils.downloadExcel(TenantPayTemplate.class, collect, map, "充值流水统计");
    }

    // 转账
    @RequestMapping({"retryPay"})
    @ResponseBody
    public ResultDto retryPay(String tenant_pay_id) {
        TenantPay tenantPay = this.tenantPayService.getById(tenant_pay_id);
        boolean result = transferRecordService.transfer(tenantPay);
        if (result) {
            ResultDto resultDto = new ResultDto();
            resultDto.setCode(1);
            return resultDto;
        }
        ResultDto resultDto = new ResultDto();
        resultDto.setMsg("转账失败");
        resultDto.setCode(0);
        return resultDto;
    }

    // 人工转账
    @RequestMapping({"manRetryPay"})
    @ResponseBody
    public ResultDto manRetryPay(HttpServletResponse response, HttpServletRequest request, String tenant_pay_id, String ammeterId, String amount) {
        ResultDto resultDto = new ResultDto();
        TenantPay tenantPay = this.tenantPayService.getById(tenant_pay_id);
        if (StringUtils.isBlank(tenantPay)) {
            resultDto.setCode(0);
            resultDto.setMsg("数据出错");
            return resultDto;
        }
        tenantPay.setIsArrive(0);
        tenantPay.setRemark("");
        boolean b = this.tenantPayService.updateById(tenantPay);
        if (b) {
            resultDto.setCode(1);
        } else {
            resultDto.setCode(0);
            resultDto.setMsg("修改失败");
        }
        return resultDto;
    }

    /**
     * 扣款转账
     *
     * @param trueAmount 转账金额
     * @param remark     备注
     */
    @RequestMapping({"deduct"})
    @ResponseBody
    public ResultDto retract(String tenant_pay_id, Double trueAmount, String remark) {
        TenantPay tenantPay = this.tenantPayService.getById(tenant_pay_id);
        ResultDto resultDto = new ResultDto();
        if (trueAmount == 0) {
            // 直接更改转账状态
            tenantPay.setIsArrive(0);
            tenantPay.setRemark(remark);
            boolean result = this.tenantPayService.updateById(tenantPay);
            if (result) {
                resultDto.setCode(1);
            } else {
                resultDto.setCode(0);
                resultDto.setMsg("扣款转账失败");
            }
        } else {
            // 重新设置金额，进入正常转账流程
            tenantPay.setPayAmouont(trueAmount);
            boolean result = transferRecordService.transfer(tenantPay);
            if (result) {
                resultDto.setCode(1);
            } else {
                resultDto.setCode(0);
                resultDto.setMsg("扣款转账失败");
            }
        }
        return resultDto;
    }

}
